package cn.desk.commons.listener;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import cn.desk.commons.action.BaseAction;
import cn.desk.commons.entity.BaseEntity;
import cn.desk.commons.entity.MessageInfo;
import cn.desk.commons.service.IBaseService;
import cn.desk.message.entity.Message;

import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.PreResultListener;

public class MessageListener implements PreResultListener {
	private IBaseService<Message> service;

	@Override
	public void beforeResult(ActionInvocation invocation, String resultCode) {
		BaseAction<?> action = (BaseAction<?>) invocation.getAction();
		List<MessageInfo> actionErrors = action.getActionErrorList();
		action.setActionErrors(fullActionMessage(actionErrors));

		List<MessageInfo> actionMessages = action.getActionMessage();
		action.setActionMessages(fullActionMessage(actionMessages));

		Map<String, List<MessageInfo>> fieldErrorMap = action
				.getFieldErrorMap();
		action.setFieldErrors(fullFieldError(fieldErrorMap));
	}

	private Map<String, List<String>> fullFieldError(
			Map<String, List<MessageInfo>> fieldErrorMap) {
		Map<String, List<String>> result = new HashMap<String, List<String>>();
		if (fieldErrorMap != null) {
			List<MessageInfo> messageInfos;
			List<String> messages;
			for (Map.Entry<String, List<MessageInfo>> en : fieldErrorMap
					.entrySet()) {
				messageInfos = en.getValue();
				messages = fullActionMessage(messageInfos);
				result.put(en.getKey(), messages);
			}
		}
		return result;
	}

	private List<String> fullActionMessage(List<MessageInfo> messageInfos) {
		List<String> errorIds = new ArrayList<String>();
		if (messageInfos != null) {
			for (MessageInfo mi : messageInfos) {
				errorIds.add(mi.getMessage());
			}
			String errorId[] = new String[errorIds.size()];
			errorIds.toArray(errorId);
			List<Message> resultMessage = service.listInByProperty(
					Message.class, "id", errorId);
			Map<String, String> map = new HashMap<String, String>();
			for (Message m : resultMessage) {
				map.put(m.getId(), m.getMessage());
			}
			for (MessageInfo mi : messageInfos) {
				String message = map.get(mi.getMessage());
				if (message != null) {
					mi.setMessage(message);
				}
			}
		}
		return getMessage(messageInfos);
	}

	private List<String> getMessage(List<MessageInfo> resultMessage) {
		List<String> messages = new ArrayList<String>();
		if (resultMessage != null) {
			for (MessageInfo mi : resultMessage) {
				messages.add(realMessage(mi));
			}
		}
		return messages;
	}

	private String realMessage(MessageInfo mi) {
		String m = mi.getMessage();
		BaseEntity be = mi.getEntity();
		if (be != null) {
			m = m.replace("%N", be.getDisplayName());
			m = m.replace("%V", String.valueOf(be.getValue()));
		}
		Object[] values = mi.getValues();
		if (values != null) {
			for (int i = 0; i < values.length; i++) {
				m = m.replace("%" + 1, String.valueOf(values[i]));
			}
		}
		return m;
	}

	public IBaseService<Message> getService() {
		return service;
	}

	public void setService(IBaseService<Message> service) {
		this.service = service;
	}

}